const vscode = require('vscode');
const fs = require('fs');
const path = require('path');
const {
    War3Helper,
    SetConfigList,
    GetConfigList,
    GetWar3Table,
    SetWar3Table,
    run_lua,
    UpdateWar3Config,
    isFileLocked,
} = require('./lua');

/**
 * 插件被激活时触发，所有代码总入口
 * @param {vscode.ExtensionContext} context 插件上下文
 */
module.exports = async function (context) {
    function registerToggleCommand(context, commandName, configKey) {
        context.subscriptions.push(vscode.commands.registerCommand(commandName, async function () {
            await SetConfigList(configKey, !await GetConfigList(configKey));
        }));
    }

    registerToggleCommand(context, 'war3helper.OpenLockMouse', "窗口锁定鼠标");
    registerToggleCommand(context, 'war3helper.OpenFixedRatioWindowed', "固定窗口比例");
    registerToggleCommand(context, 'war3helper.OpenWar3Window', "窗口化");
    registerToggleCommand(context, 'war3helper.OpenWideScreen', "宽屏模式");
    registerToggleCommand(context, 'war3helper.OpenWar3OpenGL', "OpenGL");
    registerToggleCommand(context, 'war3helper.OpenAutoStartGame', "多人模式");
    registerToggleCommand(context, 'war3helper.OpenBuildLuac', "BuildLuac");
    registerToggleCommand(context, 'war3helper.OpenBuildSlk', "BuildSlk");
    registerToggleCommand(context, 'war3helper.OpenEncodeKKWEJass', "EncodeKKWEJass");
    registerToggleCommand(context, 'war3helper.OpenYDWEJapi', "Japi环境");

    // 在模块作用域内定义一个对象来存储已创建的 Webview 面板
    const webviewPanels = {};
    global.webviewPanels = webviewPanels;

    context.subscriptions.push(vscode.commands.registerCommand('war3helper.openWar3TableTemplate', async function (label) {
        // 检查是否存在已创建的 Webview 面板
        let panel = webviewPanels[label];

        if (!panel || panel._isDisposed) {
            // 如果不存在或已被销毁，则创建新的 Webview 面板
            panel = vscode.window.createWebviewPanel(
                label,
                label,
                vscode.ViewColumn.One,
                {
                    enableScripts: true,
                    retainContextWhenHidden: true,
                }
            );

            // 将新创建的 Webview 面板存储到对象中
            webviewPanels[label] = panel;

            // 当 Webview 面板被关闭时，从对象中移除该面板的引用
            panel.onDidDispose(() => {
                delete webviewPanels[label];
            });

            const parentDir = path.dirname(__dirname);
            await fs.readFile(path.join(parentDir, 'src\\html\\ItemTemplate.html'), 'utf8', async (err, data) => {
                panel.webview.html = data;

                panel.webview.onDidReceiveMessage(async (message) => {
                    switch (message.command) {
                        case 'Create':
                            await run_lua('CreateItemTemplate', [message.data])
                            break;
                    }
                });
            });
        } else {
            panel.reveal();
        }
    }));

    // 注册打开 Webview 的命令
    context.subscriptions.push(vscode.commands.registerCommand('war3helper.openCustomConfig', async function (label) {
        // 检查是否存在已创建的 Webview 面板
        let panel = webviewPanels[label];

        if (!panel || panel._isDisposed) {
            // 如果不存在或已被销毁，则创建新的 Webview 面板
            panel = vscode.window.createWebviewPanel(
                label,
                label,
                vscode.ViewColumn.One,
                {
                    enableScripts: true,
                    retainContextWhenHidden: true,
                }
            );

            // 将新创建的 Webview 面板存储到对象中
            webviewPanels[label] = panel;

            // 当 Webview 面板被关闭时，从对象中移除该面板的引用
            panel.onDidDispose(() => {
                delete webviewPanels[label];
            });

            const parentDir = path.dirname(__dirname);
            await fs.readFile(path.join(parentDir, 'src\\html\\CustomConfig.html'), 'utf8', async (err, data) => {
                panel.webview.html = data;

                const ProjectConfig = await GetWar3Table('ProjectConfig.json');
                if (ProjectConfig != null) {
                    ProjectConfig.forEach(element => {
                        panel.webview.postMessage({
                            type: "addNewItem",
                            data: element || {},
                        })
                    });
                }
            });

            panel.webview.onDidReceiveMessage(async (message) => {
                switch (message.command) {
                    case 'addNewItem':
                        panel.webview.postMessage({
                            type: "addNewItem",
                            data: {},
                        })
                        break;
                    case 'Update':
                        SetWar3Table('ProjectConfig.json', JSON.parse(message.data))
                        break;
                }
            });
        } else {
            panel.reveal();
        }
    }));

    // 注册打开 Webview 的命令
    context.subscriptions.push(vscode.commands.registerCommand('war3helper.openWPSConfig', async function (label) {
        // 检查是否存在已创建的 Webview 面板
        let panel = webviewPanels[label];

        if (!panel || panel._isDisposed) {
            // 如果不存在或已被销毁，则创建新的 Webview 面板
            panel = vscode.window.createWebviewPanel(
                'WPS表格ID',
                'WPS表格ID',
                vscode.ViewColumn.One,
                {
                    enableScripts: true,
                    retainContextWhenHidden: true,
                }
            );

            // 将新创建的 Webview 面板存储到对象中
            webviewPanels[label] = panel;

            // 当 Webview 面板被关闭时，从对象中移除该面板的引用
            panel.onDidDispose(() => {
                delete webviewPanels[label];
            });

            const parentDir = path.dirname(__dirname);
            await fs.readFile(path.join(parentDir, 'src\\html\\WPSID.html'), 'utf8', async (err, data) => {
                panel.webview.html = data;

                const WPSID = await GetConfigList('WPSID');
                if (WPSID != null) {
                    WPSID.forEach(element => {
                        panel.webview.postMessage({
                            type: "addNewItem",
                            data: element,
                        })
                    });
                }
            });

            panel.webview.onDidReceiveMessage(async (message) => {
                switch (message.command) {
                    case 'addNewItem':
                        const input = await vscode.window.showInputBox({
                            prompt: `请输入WPS表格ID`,
                            placeHolder: 'WPS表格ID'
                        });

                        if (input !== undefined) {
                            panel.webview.postMessage({
                                type: "addNewItem",
                                data: input,
                            })
                            vscode.window.showInformationMessage(`添加WPS表格ID:${input}`);
                        }
                        break;
                    case 'Update':
                        SetConfigList('WPSID', JSON.parse(message.data))
                        break;
                }
            });
        } else {
            panel.reveal();
        }
    }));

    // 注册打开 Webview 的命令
    context.subscriptions.push(vscode.commands.registerCommand('war3helper.openVirtualPath', async function (label) {
        // 检查是否存在已创建的 Webview 面板
        let panel = webviewPanels[label];

        if (!panel || panel._isDisposed) {
            panel = vscode.window.createWebviewPanel(
                '虚拟MPQ',
                '虚拟MPQ',
                vscode.ViewColumn.One,
                {
                    enableScripts: true,
                    retainContextWhenHidden: true,
                }
            );

            // 将新创建的 Webview 面板存储到对象中
            webviewPanels[label] = panel;

            // 当 Webview 面板被关闭时，从对象中移除该面板的引用
            panel.onDidDispose(() => {
                delete webviewPanels[label];
            });

            const parentDir = path.dirname(__dirname);
            await fs.readFile(path.join(parentDir, 'src\\html\\VirtualPath.html'), 'utf8', async (err, data) => {
                panel.webview.html = data;

                const VirtualPath = await GetConfigList('VirtualPath');

                VirtualPath.forEach(element => {
                    panel.webview.postMessage({
                        type: "addNewItem",
                        data: element,
                    })
                });
            });

            panel.webview.onDidReceiveMessage(async (message) => {
                switch (message.command) {
                    case 'addNewItem':
                        const input = await vscode.window.showInputBox({
                            prompt: `请输入虚拟MPQ路径`,
                            placeHolder: '虚拟MPQ路径'
                        });

                        if (input !== undefined) {
                            panel.webview.postMessage({
                                type: "addNewItem",
                                data: { path: input, prefix: "" },
                            })
                            vscode.window.showInformationMessage(`添加虚拟MPQ路径:${input}`);
                        }
                        break;
                    case 'Update':
                        SetConfigList('VirtualPath', JSON.parse(message.data))
                        break;
                }
            });
        }
        else {
            panel.reveal();
        }
    }));


    context.subscriptions.push(vscode.commands.registerCommand('war3helper.RunWar3Map', async function () {
        let MapPath = await GetConfigList("MapPath")
        if (!MapPath) {
            vscode.window.showErrorMessage('没有地图路径...');
            return;
        }

        if (await GetConfigList("多人模式")) {
            const input = await vscode.window.showInputBox({
                prompt: `玩家数量`,
                placeHolder: '请输入玩家数量',
                validateInput: (value) => {
                    if (!/^\d+$/.test(value)) {
                        return '请输入一个有效的数字';
                    }
                    if (value === '0') {
                        return "玩家数量不能为0"
                    }
                    return null; // 输入有效时返回 null
                }
            });

            if (input !== undefined) {
                await vscode.commands.executeCommand("war3helper.updateConfig");
                await run_lua("RunWar3MapHost", [String(input)]);
            }
        }
        else {
            await vscode.commands.executeCommand("war3helper.updateConfig");
            await run_lua("RunWar3Map");
        }
    }));
    context.subscriptions.push(vscode.commands.registerCommand('war3helper.RunWar3TargetMap', async function (uri) {
        let MapPath = await GetConfigList("MapPath")
        if (!MapPath) {
            vscode.window.showErrorMessage('没有地图路径...');
            return;
        }
        await run_lua("RunWar3TargetMap", [uri.fsPath]);
    }));

    async function updateMapInfo(key, prompt, placeholder) {
        let MapPath = await GetConfigList("MapPath")
        if (!MapPath) {
            vscode.window.showErrorMessage('没有地图路径...');
            return;
        }

        const input = await vscode.window.showInputBox({
            prompt: prompt,
            placeHolder: placeholder
        });
        if (input !== undefined && input.trim() !== '') {
            let MapInfo = await GetWar3Table("MapInfo.json");
            if (MapInfo != null) {
                await run_lua('SetMapInfo', [key, String(input)])
            }
        }
    }

    context.subscriptions.push(vscode.commands.registerCommand('war3helper.LoadingScreenPath', async () => {
        await updateMapInfo("LoadingScreenPath", `请输入载入图路径`, '载入图路径');
    }));

    context.subscriptions.push(vscode.commands.registerCommand('war3helper.MapVersion', async () => {
        await updateMapInfo("MapVersion", `请输入地图版本`, '地图版本');
    }));

    context.subscriptions.push(vscode.commands.registerCommand('war3helper.MapName', async () => {
        await updateMapInfo("MapName", `请输入地图名字`, '地图名字');
    }));

    context.subscriptions.push(vscode.commands.registerCommand('war3helper.MapAuthor', async () => {
        await updateMapInfo("MapAuthor", `请输入地图作者名字`, '地图作者');
    }));

    context.subscriptions.push(vscode.commands.registerCommand('war3helper.SaveUnitXlsx', async () => {
        let MapPath = await GetConfigList("MapPath")
        if (!MapPath) {
            vscode.window.showErrorMessage('没有地图路径...');
            return;
        }

        let xlsxPath = await GetConfigList('单位物编表格');
        if (xlsxPath) {
            await run_lua('ConvertUnitXlsx', [xlsxPath, "Save"])
        }
    }));
    context.subscriptions.push(vscode.commands.registerCommand('war3helper.OutUnitXlsx', async () => {
        let MapPath = await GetConfigList("MapPath")
        if (!MapPath) {
            vscode.window.showErrorMessage('没有地图路径...');
            return;
        }

        let xlsxPath = await GetConfigList('单位物编表格');
        if (xlsxPath) {
            await run_lua('ConvertUnitXlsx', [xlsxPath, "Load"])
        }
    }));
    context.subscriptions.push(vscode.commands.registerCommand('war3helper.SetLocalName', async () => {
        let MapPath = await GetConfigList("MapPath")
        if (!MapPath) {
            vscode.window.showErrorMessage('没有地图路径...');
            return;
        }

        const input = await vscode.window.showInputBox({
            prompt: `请输入本地玩家名`,
            placeHolder: '本地玩家名'
        });

        if (input !== undefined) {
            try {
                const parentDir = path.dirname(__dirname);
                const War3Registry = path.join(parentDir, 'src\\War3Registry.lua');

                await run_lua(War3Registry, ["LocalUserName", input])
                SetConfigList('LocalUserName', String(input))
                vscode.window.showInformationMessage(`设置本地玩家名为:${input}`);
            } catch (error) {
                War3Helper.error(`选择war3文件时出错:${error}`);
            }
        }
    }));
    context.subscriptions.push(vscode.commands.registerCommand('war3helper.openScriptrunner', async () => {
        const workspaceFolder = vscode.workspace.workspaceFolders[0];

        // 获取工作区根目录的文件系统条目
        const entries = await vscode.workspace.fs.readDirectory(workspaceFolder.uri);

        // 定义要排除的文件夹
        const excludeFolders = new Set(['.', '.git', '.build', '.vscode']);

        // 创建选项列表，第一个是清空选项
        const folders = [{
            label: '$(clear-all) 清空云脚本',
            description: '清除当前云脚本设置',
            value: ''  // 空值表示清空
        }];

        // 添加文件夹选项
        for (const [name, type] of entries) {
            if (type === vscode.FileType.Directory && !excludeFolders.has(name)) {
                folders.push({
                    label: `$(folder) ${name}`,
                    description: '文件夹',
                    value: name
                });
            }
        }

        // 显示快速选择菜单
        const selected = await vscode.window.showQuickPick(folders, {
            placeHolder: '选择云脚本文件夹'
        });

        if (selected) {
            if (selected.value === '') {
                SetConfigList('Scriptrunner', null);
            } else {
                SetConfigList('Scriptrunner', selected.value);
            }
        }
    }));
    context.subscriptions.push(vscode.commands.registerCommand('war3helper.openMapPath', async () => {
        const workspaceFolder = vscode.workspace.workspaceFolders[0];

        // 获取工作区中的所有 w3x 和 w3m 文件
        const mapFiles = await vscode.workspace.findFiles('**/*.{w3x,w3m}');

        // 创建选项列表，第一个是清空选项
        const files = [{
            label: '$(clear-all) 清空地图路径',
            description: '清除当前地图设置',
            value: ''  // 空值表示清空
        }];

        // 添加地图文件选项
        for (const file of mapFiles) {
            const relativePath = path.relative(workspaceFolder.uri.fsPath, file.fsPath);
            files.push({
                label: `$(file) ${path.basename(relativePath)}`,
                description: path.dirname(relativePath),
                value: relativePath
            });
        }

        // 显示快速选择菜单
        const selected = await vscode.window.showQuickPick(files, {
            placeHolder: '选择地图文件'
        });

        if (selected) {
            await SetConfigList('MapPath', selected.value);
            await vscode.commands.executeCommand("war3helper.refresh");
        }
    }));

    // 注册打开 Webview 的命令
    context.subscriptions.push(vscode.commands.registerCommand('war3helper.openLoadPath', async (label) => {
        // 检查是否存在已创建的 Webview 面板
        let panel = webviewPanels[label];

        if (!panel || panel._isDisposed) {
            // 如果不存在或已被销毁，则创建新的 Webview 面板
            panel = vscode.window.createWebviewPanel(
                label,
                label,
                vscode.ViewColumn.One,
                {
                    enableScripts: true,
                    retainContextWhenHidden: true,
                }
            );

            // 将新创建的 Webview 面板存储到对象中
            webviewPanels[label] = panel;

            // 当 Webview 面板被关闭时，从对象中移除该面板的引用
            panel.onDidDispose(() => {
                delete webviewPanels[label];
            });
            const parentDir = path.dirname(__dirname);
            await fs.readFile(path.join(parentDir, 'src\\html\\LoadPath.html'), 'utf8', async (err, data) => {
                panel.webview.html = data;

                const LoadPath = await GetConfigList('LoadPath');
                if (LoadPath != null) {
                    LoadPath.forEach(element => {
                        panel.webview.postMessage({
                            type: "addNewItem",
                            data: element,
                        })
                    });
                }
            });

            panel.webview.onDidReceiveMessage(async (message) => {
                switch (message.command) {
                    case 'addNewItem':
                        const input = await vscode.window.showInputBox({
                            prompt: `请输入每次运行地图要注入的文件路径`,
                            placeHolder: '每次运行地图要注入的文件路径'
                        });

                        if (input !== undefined) {
                            panel.webview.postMessage({
                                type: "addNewItem",
                                data: input,
                            })
                            vscode.window.showInformationMessage(`添加每次运行地图要注入的文件路径:${input}`);
                        }
                        break;
                    case 'Update':
                        SetConfigList('LoadPath', JSON.parse(message.data))
                        break;
                }
            });
        } else {
            panel.reveal();
        }
    }));

    context.subscriptions.push(vscode.commands.registerCommand('war3helper.selectWar3', async () => {
        // 获取上次的War3路径
        let War3Registry = await GetConfigList('War3Registry');

        let defaultUri;
        if (War3Registry) {
            defaultUri = War3Registry["InstallPath"];
        }
        console.log("defaultUri:", defaultUri);
        const options = {
            canSelectMany: false,
            openLabel: '选择文件',
            defaultUri: vscode.Uri.file(defaultUri), // 设置默认打开路径
            filters: {
                'war3.exe': ['exe']
            }
        };

        const selectedFiles = await vscode.window.showOpenDialog(options);

        if (selectedFiles && selectedFiles.length > 0) {
            const selectedFile = selectedFiles[0];
            const fileName = path.basename(selectedFile.fsPath);

            if (fileName.toLowerCase() === 'war3.exe') {
                const workspaceFolder = vscode.workspace.workspaceFolders[0].uri.fsPath;
                const War3Config = await GetWar3Table('War3Config.json');
                const War3Registry = War3Config['War3Registry'] ?? {};
                War3Registry['GamePath'] = selectedFile.fsPath;
                War3Registry['InstallPath'] = path.dirname(selectedFile.fsPath);
                await SetWar3Table('War3Config.json', War3Config);
                War3Helper.info(`选择war3路径成功!`);
            } else {
                War3Helper.error('必须选择 war3.exe 文件');
            }
        }
    }));

    context.subscriptions.push(vscode.commands.registerCommand('war3helper.selectPlatform', async () => {
        const input = await vscode.window.showQuickPick(
            ['KK平台', 'YY平台', '无'],
            { placeHolder: '请选择平台环境' }
        );

        if (input) {
            SetConfigList('平台环境', String(input));
            vscode.window.showInformationMessage(`选择平台环境:${String(input)}`);
        }
    }));

    context.subscriptions.push(vscode.commands.registerCommand('war3helper.SlkMap', async function () {
        let MapPath = await GetConfigList("MapPath")
        if (!MapPath) {
            vscode.window.showErrorMessage('没有地图路径...');
            return;
        }

        const workspaceFolder = vscode.workspace.workspaceFolders[0].uri.fsPath;
        if (await isFileLocked(workspaceFolder + "\\MapBuild.w3x")) {
            vscode.window.showErrorMessage('地图正在打包中，请稍等...');
            return;
        }

        await run_lua("SlkMap")

        let Scripts = (await GetConfigList('PluginScripts')) ?? []

        for (let i = 0; i < Scripts.length; i++) {
            var script = Scripts[i];
            if (script['type'] == '生成发布版后执行' && script['enable'] == true) {
                await run_lua(path.join(workspaceFolder, ".tools", script['name'] + ".lua"))
            }
        }
        await vscode.commands.executeCommand("war3helper.update");
    }));
    context.subscriptions.push(vscode.commands.registerCommand('war3helper.MergeBuild', async function () {
        let MapPath = await GetConfigList("MapPath")
        if (!MapPath) {
            vscode.window.showErrorMessage('没有地图路径...');
            return;
        }
        const workspaceFolder = vscode.workspace.workspaceFolders[0].uri.fsPath;
        MapPath = `${workspaceFolder}\\${MapPath}`;
        if (await isFileLocked(MapPath)) {
            vscode.window.showErrorMessage('地图被占用，无法导入...');
            return;
        }
        await run_lua('MergeBuild')
    }));

    // 注册刷新命令
    context.subscriptions.push(vscode.commands.registerCommand('war3helper.refresh', async function () {
        let MapPath = await GetConfigList("MapPath")
        if (!MapPath) {
            vscode.window.showErrorMessage('没有地图路径...');
            return;
        }
        MapPath = `${vscode.workspace.workspaceFolders[0].uri.fsPath}\\${MapPath}`;
        await run_lua('OpenBuild')
    }));

    // 注册刷新命令
    context.subscriptions.push(vscode.commands.registerCommand('war3helper.WPSClone', async function () {
        const workspaceFolder = vscode.workspace.workspaceFolders[0].uri.fsPath;
        const War3Config = path.join(workspaceFolder, '\\.vscode\\War3Config.json');

        if (await fs.existsSync(War3Config)) {
            await fs.readFile(War3Config, 'utf8', async (err, data) => {
                if (err) {
                    return;
                }

                const jsonObject = JSON.parse(data);
                if (jsonObject["WPSID"] == null) {
                    vscode.window.showErrorMessage('WPS没有配置ID!');
                }
                for (const id in jsonObject["WPSID"]) {
                    await run_lua("CloneWPS", [jsonObject["WPSID"][id]])
                }
            });
        }
    }));
    context.subscriptions.push(vscode.commands.registerCommand('war3helper.LaunchWar3', async function () {
        let MapPath = await GetConfigList("MapPath")
        if (!MapPath) {
            vscode.window.showErrorMessage('没有地图路径...');
            return;
        }
        await run_lua('LaunchWar3')
    }));
}